const { isEmpty, fromPairs } = require('lodash');

/**
 * 数据操作扩展
*/
module.exports = {
  /**
	 * 数据插入
	* @param {EggMySQL} db 操作的数据库
	* @param {String} table 数据库表名
	* @param {Object} row 需要插入的数据
	*/
  async createDb(db, table, row) {
    const result = await db.insert(table, row);
    return result;
  },

  /**
	 * 数据更新
	* @param {EggMySQL} db 操作的数据库
	* @param {String} table 数据库表名
	* @param {Object} row 需要跟新的数据
	* @param {Object} option 扩展参数
	*/
  async updateDb(db, table, row, option) {
    const result = await db.update(table, row, option);
    return result;
  },

  /**
	 * 单条数据查找
	* @param {EggMySQL} db 操作的数据库
	* @param {String} table 数据库表名
	* @param {Object} row 需要查找的数据
	*/
  async findOneDb(db, table, row) {
    const result = await db.get(table, row);
    return result;
  },

  /**
	 * 多条数据查找
	* @param {EggMySQL} db 操作的数据库
	* @param {String} table 数据库表名
	* @param {Object} option 条件查询
  * @example option
	{
			where: { status: 'draft', author: ['author1', 'author2'] }, // WHERE 条件
			columns: ['author', 'title'], // 要查询的表字段
			orders: [['created_at','asc'], ['id','desc']], // 排序方式
			limit: 10, // 返回数据量
			offset: 0, // 数据偏移量
		});
	*/
  async findAllDb(db, table, option) {
    const result = await db.select(table, option);
    return result;
  },

  /**
	 * 删除数据
	* @param {EggMySQL} db 操作的数据库
	* @param {String} table 数据库表名
	* @param {Object} row 需要删除的数据
	*/
  async deleteDb(db, table, row) {
    const result = await db.delete(table, row);
    return result;
  },

  /**
	 * 统计查询结果
	 * @param {EggMySQL} db 操作的数据库
		* @param {String} table 数据库表名
		* @param {Object} row 需要统计的数据
	*/
  async countDb(db, table, row) {
    const result = await db.count(table, row);
    return result;
  },

  /**
	 * 自定义sql语句执行
	* @param {EggMySQL} db 操作的数据库
	* @param {String} sql 合法的执行语句
	*/
  async executeSql(db, sql) {
    const result = await db.query(sql);
    return result;
  },

  /**
	 * 自定义sql语句模糊搜索
	* @param db
	* @param table
	* @param options
  * @example option
	{
			where: { status: 'draft' }, // WHERE 条件
			columns: ['author', 'title'], // 要查询的表字段
			orders: [['created_at','desc'], ['id','desc']], // 排序方式
			pageSize: 10, // 分页数据
			pageNum: 1, // 当前页码
		});
	*/
  async queryWithLike(db, table, options = {}) {
    const { where = {}, columns = [], orders = [], pageSize, pageNum } = options;

    let sql = `select ${isEmpty(columns) ? '*' : columns.join(',')} from ${table}`; // sql语句
    let countSql = `select ${isEmpty(columns) ? 'count(*) as count' : `count(${columns.join(',')}) as count`} from ${table}`; // sql语句
    if (isEmpty(where)) {
      // 字段排序
      if (orders?.length) {
        const orderObject = fromPairs(orders);
        sql += ' order by';
        Object.keys(orderObject).forEach((key, index) => {
          sql += ` ${key} ${orderObject[key]}${index === orders.length - 1 ? '' : ','}`;
        });
      }
      if (pageSize && pageNum) {
        sql += ` limit ${(parseInt(pageNum) - 1) * parseInt(pageSize)},${parseInt(pageSize)}`;
      }
    } else {
      Object.keys(where).forEach((key, index) => {
        if (index === 0) {
          sql += ` where ${key} like "%${where[key]}%"`;
          countSql += ` where ${key} like "%${where[key]}%"`;
        } else {
          // and是两个条件都必须满足，or是或的关系
          sql += ` and ${key} like "%${where[key]}%"`;
          countSql += ` and ${key} like "%${where[key]}%"`;
        }
      });
      // 字段排序
      if (orders?.length) {
        const orderObject = fromPairs(orders);
        sql += ' order by';
        Object.keys(orderObject).forEach((key, index) => {
          sql += ` ${key} ${orderObject[key]}${index === orders.length - 1 ? '' : ','}`;
        });
      }
      if (pageSize && pageNum) {
        sql += ` limit ${(parseInt(pageNum) - 1) * parseInt(pageSize)},${parseInt(pageSize)}`;
      }
    }
    console.log('sql', sql);

    const result = await db.query(sql);
    const countResult = await db.query(countSql);
    return {
      list: result,
      total: countResult[0].count,
      pageSize: parseInt(pageSize),
      pageNum: parseInt(pageNum),
    };
  },
};
